const DataModel = require('../model/DataModel');
const crypto = require('crypto');
const zlib = require('zlib');

const SUCCESS_CODE = 0;

// 全局共享数据状态（作为 '资源' 的源头）
let resourceState = {
  // getETag 接口返回的数据
  etagData: {
    content: '这是一个带有ETag的响应。',
    msg: 'ETag设置成功'
  },
  // 用于生成 ETag 的版本号，变化时 ETag 改变
  version: 1,
  // 上次更新时间
  updatedAt: Date.now()
};

// 工具函数：根据当前资源状态生成 ETag
function generateETag() {
  const stateStr = JSON.stringify({
    version: resourceState.version,
    content: resourceState.etagData.content
  });
  return crypto.createHash('md5').update(stateStr).digest('hex');
}



/**
 * basCross-domain settings
 *
 * @param req request
 * @param res response
 */
const baseSetting = (req, res, next) => {
  var token = req.headers['authorization'];
  //设置允许跨域的域名，*代表允许任意域名跨域
  res.header('Access-Control-Allow-Origin', '*');
  //允许的header类型
  res.header('Access-Control-Allow-Headers', '*');
  //跨域允许的请求方式
  res.header(
    'Access-Control-Allow-Methods',
    'DELETE,PUT,POST,GET,OPTIONS,PATCH'
  );
  //让options请求快速返回
  if (req.method === 'OPTIONS') res.send(200);
  // else if(req.originalUrl.indexOf('/tpc/') != -1){
  //   token ? next() : res.json(401, { error: 'token认证失败！' })
  // }
  else {
    next();
  }
};

/**
 * Get tpc list.
 *
 * @param req request
 * @param res response
 */
const getTpcList = (req, res) => {
  let result = DataModel.tpcList.map((item) => {
    let obj = {
      id: item['id'],
      name: item['name'],
      gitUrl: item['gitUrl'],
    };
    return obj;
  });
  res.send({ code: SUCCESS_CODE, data: result, msg: '查询成功' });
};

/**
 * patch tpc info.
 *
 * @param req request
 * @param res response
 */
const patchTpcInfo = (req, res) => {
  let tpcList = JSON.parse(JSON.stringify(DataModel.tpcList));
  let requestBody = req.body;

  if (!(requestBody instanceof Object) || !requestBody.id) {
    res.json(500, { error: '参数错误！' });
  }

  let result = tpcList.filter((item) => {
    return item.id == requestBody.id;
  });

  delete requestBody['id'];
  let bodyKeys = Object.keys(requestBody);

  if (result.length > 0 && bodyKeys.length > 0) {
    let obj = result[0];
    bodyKeys.forEach((item) => {
      if (obj[item]) {
        obj[item] = requestBody[item];
      }
    });
    res.send({ code: SUCCESS_CODE, data: obj, msg: '修改成功' });
  } else {
    res.send({ code: SUCCESS_CODE, data: [], msg: '修改成功' });
  }
};

/**
 * search tpc detail.
 *
 * @param req request
 * @param res response
 */
const postTpcDetail = (req, res) => {
  if (req.body.id) {
    let result = DataModel.tpcList.filter((item) => {
      return item.id == req.body.id;
    });
    res.send({ code: SUCCESS_CODE, data: result, msg: '提交成功' });
  } else {
    res.send({ code: SUCCESS_CODE, data: [], msg: '提交成功' });
  }
};

/**
 * put tpc list.
 *
 * @param req request
 * @param res response
 */
const putTpcInfo = (req, res) => {
  let tpcList = JSON.parse(JSON.stringify(DataModel.tpcList));
  let requestBody = req.body;

  if (!(requestBody instanceof Object) || !requestBody.id) {
    res.json(500, { error: '参数错误！' });
  }

  let result = tpcList.filter((item) => {
    return item.id == requestBody.id;
  });

  delete requestBody['id'];
  let bodyKeys = Object.keys(requestBody);

  if (result.length > 0 && bodyKeys.length > 0) {
    let obj = result[0];
    bodyKeys.forEach((item) => {
      if (obj[item]) {
        obj[item] = requestBody[item];
      }
    });
    res.send({ code: SUCCESS_CODE, data: obj, msg: '修改成功', params: req.query});
  } else {
    res.send({ code: SUCCESS_CODE, data: [], msg: '修改成功', params: req.query});
  }
};

/**
 * delete tpc item.
 *
 * @param req request
 * @param res response
 */
const deleteTpcInfo = (req, res) => {
  if (req.body.id) {
    res.send({
      code: SUCCESS_CODE,
      data: `id为${req.body.id}的数据删除成功！`,
      msg: '操作成功',
    });
  } else {
    res.json(500, { error: '参数错误！' });
  }
};

/**
 * A request is returned after a delay of 10s.
 *
 * @param req request
 * @param res response
 */
const getDelay = (req, res) => {
  setTimeout(() => {
    res.send({
      code: SUCCESS_CODE,
      data: `id为${req.body.id}的数据删除成功！`,
      msg: '延迟10s后返回的数据。',
    });
  }, 10000);
};

/**
 * A redirect request.
 *
 * @param req request
 * @param res response
 */
const getRedirect = (req, res) => {
  res.writeHead(302, { Location: '/tpc/redirect2' });
  res.end();
};

/**
 * Second redirect.
 *
 * @param req request
 * @param res response
 */
const getRedirect2 = (req, res) => {
  res.writeHead(302, {
    Location: 'https://www.openharmony.cn',
  });
  res.end();
};

/**
 * GZIP compression for GET requests.
 *
 * @param req request
 * @param res response
 */
const getGzip = (req, res) => {
  // 1. 准备要发送的数据
  const data = {
    code: SUCCESS_CODE,
    data: '这是一个经过GZIP压缩的GET请求响应。',
    msg: 'GZIP压缩成功',
  };

  const jsonString = JSON.stringify(data);
  const inputBuffer = Buffer.from(jsonString, 'utf8');

  // 2. 使用 zlib.gzipSync 进行同步压缩 (简单，但阻塞)
  //    在生产环境中，对于大文件，建议使用流式压缩
  const compressedBuffer = zlib.gzipSync(inputBuffer);

  // 3. 设置正确的响应头
  res.writeHead(200, {
    'Content-Type': 'application/json; charset=utf-8', // 指明内容类型
    'Content-Encoding': 'gzip', // 告诉客户端：内容是GZIP压缩过的
    'Content-Length': compressedBuffer.length, // 压缩后的长度
    // 'Vary': 'Accept-Encoding' // 如果你同时支持 gzip/deflate/br，建议加上
  });

  // 4. 发送压缩后的二进制数据
  res.end(compressedBuffer);
};

/**
 * GZIP compression for POST requests.
 *
 * @param req request
 * @param res response
 */
const postGzip = (req, res) => {
    // 1. 准备要发送的数据
  const data = {
    code: SUCCESS_CODE,
    data: '这是一个经过GZIP压缩的GET请求响应。',
    msg: 'GZIP压缩成功',
  };

  const jsonString = JSON.stringify(data);
  const inputBuffer = Buffer.from(jsonString, 'utf8');

  // 2. 使用 zlib.gzipSync 进行同步压缩 (简单，但阻塞)
  //    在生产环境中，对于大文件，建议使用流式压缩
  const compressedBuffer = zlib.gzipSync(inputBuffer);

  // 3. 设置正确的响应头
  res.writeHead(200, {
    'Content-Type': 'application/json; charset=utf-8', // 指明内容类型
    'Content-Encoding': 'gzip', // 告诉客户端：内容是GZIP压缩过的
    'Content-Length': compressedBuffer.length, // 压缩后的长度
    // 'Vary': 'Accept-Encoding' // 如果你同时支持 gzip/deflate/br，建议加上
  });

  // 4. 发送压缩后的二进制数据
  res.end(compressedBuffer);
};

// Cache相关接口
const getNoCache = (req, res) => {
  res.setHeader('Cache-Control', 'no-cache');
  res.send({
    code: SUCCESS_CODE,
    data: '这是一个不缓存的响应。',
    msg: '无缓存成功',
  });
};

/**
 * ✅ getETag - 返回主数据，并支持 ETag 缓存
 * 这是你要测试的主接口
 */
const getETag = (req, res) => {
  console.log('[getETag] 收到请求');

  // 1. 生成当前资源的 ETag
  const currentETag = generateETag();
  const clientETag = req.headers['if-none-match'];
    console.log(clientETag);
  // 2. 检查客户端 ETag
  if (clientETag === currentETag) {
    console.log('✅ [getETag] ETag 匹配，返回 304 Not Modified');
    res.status(304).end();
  } else {
    // 3. 返回完整响应
    console.log(`❌ [getETag] ETag 不匹配或首次请求，返回 200, ETag: ${currentETag}`);
    res.status(200).set({
      'ETag': currentETag,
      'Cache-Control': 'public, max-age=3600'
    }).send({
      code: SUCCESS_CODE,
      data: resourceState.etagData.content,
      msg: resourceState.etagData.msg,
      version: resourceState.version // 便于观察
    });
  }
};

const getMaxAge = (req, res) => {
  res.setHeader('Cache-Control', 'max-age=3600');
  res.send({
    code: SUCCESS_CODE,
    data: '这是一个设置了max-age的响应。',
    msg: 'max-age设置成功',
  });
};
/**
 * ✅ getETagChange - 调用此接口会改变 resourceState，从而改变 getETag 的 ETag
 * 这是“改变 ETag”的触发器（虽然是 GET，但有副作用）
 */
const getETagChange = (req, res) => {
  console.log('[getETagChange] 收到请求 - 触发状态变更');

  // 🔥 核心：修改共享状态，使 generateETag() 产生新值
  resourceState.version += 1;
  resourceState.updatedAt = Date.now();
  // 稍微改变内容，确保 ETag 一定变
  resourceState.etagData.content = `这是一个修改了ETag的响应。触发次数: ${resourceState.version}`;
  resourceState.etagData.msg = 'ETag修改成功';

  // 为当前新状态生成 ETag
  const newETag = generateETag();

  // 返回变更确认信息
  console.log(`🔥 [getETagChange] 状态已更新，新版本: ${resourceState.version}, 新ETag: ${newETag}`);
  res.status(200).set({
    'ETag': newETag,
    'Cache-Control': 'no-cache' // 这个接口本身不鼓励缓存
  }).send({
    code: SUCCESS_CODE,
    data: `ETag 已更新至版本 ${resourceState.version}`,
    msg: '状态变更成功，主接口 ETag 已改变',
    newVersion: resourceState.version
  });
};

const getExpires = (req, res) => {
  res.setHeader('Expires', new Date(Date.now() + 3600000).toUTCString());
  res.send({
    code: SUCCESS_CODE,
    data: '这是一个设置了Expires的响应。',
    msg: 'Expires设置成功',
  });
};

const getImmutable = (req, res) => {
  res.setHeader('Cache-Control', 'immutable');
  res.send({
    code: SUCCESS_CODE,
    data: '这是一个设置了immutable的响应。',
    msg: 'immutable设置成功',
  });
};

const getLastModified = (req, res) => {
  res.setHeader('Last-Modified', new Date().toUTCString());
  res.send({
    code: SUCCESS_CODE,
    data: '这是一个设置了Last-Modified的响应。',
    msg: 'Last-Modified设置成功',
  });
};

const getLastModifiedChange = (req, res) => {
  res.setHeader('Last-Modified', new Date(Date.now() - 3600000).toUTCString());
  res.send({
    code: SUCCESS_CODE,
    data: '这是一个修改了Last-Modified的响应。',
    msg: 'Last-Modified修改成功',
  });
};


module.exports = {
  baseSetting,
  getTpcList,
  patchTpcInfo,
  postTpcDetail,
  putTpcInfo,
  deleteTpcInfo,
  getDelay,
  getRedirect,
  getRedirect2,
  getGzip,
  postGzip,
  getNoCache,
  getETag,
  getMaxAge,
  getETagChange,
  getExpires,
  getImmutable,
  getLastModified,
  getLastModifiedChange,
};
